import base64
import logging
import requests
from scrapy import signals
from itemadapter import is_item, ItemAdapter

logger = logging.getLogger(__name__)


class NewsScraperSpiderMiddleware:
    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_spider_input(self, response, spider):
        return None

    def process_spider_output(self, response, result, spider):
        for i in result:
            yield i

    def process_spider_exception(self, response, exception, spider):
        pass

    def process_start_requests(self, start_requests, spider):
        for r in start_requests:
            yield r

    def spider_opened(self, spider):
        spider.logger.info("Spider opened: %s" % spider.name)


class NewsScraperDownloaderMiddleware:
    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_request(self, request, spider):
        return None

    def process_response(self, request, response, spider):
        return response

    def process_exception(self, request, exception, spider):
        pass

    def spider_opened(self, spider):
        spider.logger.info("Spider opened: %s" % spider.name)


class ImageProcessingMiddleware:
    """处理图片下载和转换的中间件"""

    @classmethod
    def from_crawler(cls, crawler):
        return cls()

    def process_spider_output(self, response, result, spider):
        for item in result:
            if is_item(item):
                adapter = ItemAdapter(item)
                if adapter.get('image_url'):
                    try:
                        # 设置请求头，模拟浏览器行为
                        headers = {
                            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
                        }

                        # 下载图片
                        img_response = requests.get(
                            adapter.get('image_url'),
                            headers=headers,
                            timeout=10,
                            verify=False  # 如果需要忽略SSL证书验证
                        )

                        if img_response.status_code == 200:
                            # 检查内容类型
                            content_type = img_response.headers.get('content-type', '')
                            if 'image' in content_type.lower():
                                # 转换为base64
                                img_base64 = base64.b64encode(img_response.content).decode('utf-8')
                                adapter['image_base64'] = img_base64
                                adapter['image_status'] = 'success'
                                logger.info(f"Successfully processed image from {adapter.get('image_url')}")
                            else:
                                adapter['image_status'] = 'invalid_content_type'
                                logger.warning(f"Invalid content type {content_type} for {adapter.get('image_url')}")
                        else:
                            adapter['image_status'] = 'failed'
                            logger.warning(
                                f"Failed to download image from {adapter.get('image_url')}, status code: {img_response.status_code}")

                    except requests.exceptions.Timeout:
                        adapter['image_status'] = 'timeout'
                        logger.error(f"Timeout downloading image from {adapter.get('image_url')}")

                    except requests.exceptions.RequestException as e:
                        adapter['image_status'] = 'failed'
                        logger.error(f"Request error processing image from {adapter.get('image_url')}: {str(e)}")

                    except Exception as e:
                        adapter['image_status'] = 'error'
                        logger.error(f"Unexpected error processing image from {adapter.get('image_url')}: {str(e)}")
                else:
                    adapter['image_status'] = 'no_image'
            yield item

    def process_exception(self, request, exception, spider):
        logger.error(f"Middleware exception: {str(exception)}")
        return None